package com.ruoyi.common.log.aspect;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.log.annotation.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author: 吴文兵
 * @date: 2025-06-03 17:02
 */
@Aspect
@Component
public class LogAspectTest {

    private static final Logger log = LoggerFactory.getLogger(LogAspectTest.class);

    @Pointcut("@annotation(com.ruoyi.common.log.annotation.Log)")
    public void pointCut1(){
    }

    /**
     * 1.通过切点
     * @param joinPoint
     */
    @Before(value = "pointCut1()")
    public void before1(JoinPoint joinPoint){
        System.out.println("before1");

    }

    /**
     * 2.通过注解
     * @param joinPoint
     */
    @Before("@annotation(com.ruoyi.common.log.annotation.Log)")
    public void before2(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        System.out.println("before2");
        Class<?> aClass = joinPoint.getTarget().getClass();//获取类完整路径
        Signature signature = joinPoint.getSignature();//获取方法名
        Object[] args = joinPoint.getArgs();//获取参数
        String name = signature.getName();
        log.info("class:{}",aClass.getName());//class:com.ruoyi.system.controller.SysLogininforController
        log.info("name:{}",name);//name:export
        log.info("args:{}",args);//args:org.springframework.web.context.request.async.StandardServletAsyncWebRequest$LifecycleHttpServletResponse@7c65f976
        for (Object arg : args){
            log.info("arg:{}",arg);//arg:com.ruoyi.system.api.domain.SysLogininfor@37b700db
            log.info("argName:{}",arg.getClass().getName());//argName:com.ruoyi.system.api.domain.SysLogininfor
            if (arg instanceof HttpServletRequest || arg instanceof HttpServletResponse) {
                log.info("argJson:{}","Servlet Request/Response");//导出的第一个参数为httRequest解析失败
            } else {
                log.info("argJson:{}",JSON.toJSONString(arg));//argJson:{"params":{}}
            }
        }
//        log.info("args[0]:{}",args[0]);
//        log.info("argsName:{}",args[0].getClass().getName());
//        log.info("argsJson:{}", JSON.toJSONString(args[0]));//导出的第一个参数为httRequest解析失败


//        Method method = aClass.getMethod(name);
//        log.info("method:{}",method);
//        //重新调用方法
//        method.invoke(args);



    }

    /**
     * 3.参数
     * @param joinPoint
     * @param log
     */
    @Before("@annotation(log)")
    public void before3(JoinPoint joinPoint,Log log){
        System.out.println("before3");

    }


    @After("@annotation(log)")
    public void after(JoinPoint joinPoint,Log log){
        System.out.println("after");

    }
    @Around("pointCut1()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed(); // 执行原方法
        long costTime = System.currentTimeMillis() - start;
        log.info("方法耗时：{}ms", costTime);
        return result;
    }
    @AfterThrowing(pointcut = "pointCut1()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e) {
        log.error("方法 {} 抛出异常: {}", joinPoint.getSignature().getName(), e.getMessage());
    }
    @AfterReturning(pointcut = "pointCut1()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        log.info("方法返回值: {}", JSON.toJSONString(result));
    }

}